package com.hskn.hss.module.tlempincidental.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.page.TableDataInfo;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.service.ICostDictItemService;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.tlempincidental.entity.TlEmpIncidental;
import com.hskn.hss.module.tlempincidental.mapper.TlEmpIncidentalMapper;
import com.hskn.hss.module.tlempincidental.service.ITlEmpIncidentalService;
import com.hskn.hss.module.tlempincidental.to.*;
import com.hskn.hss.module.tlempincidental.vo.EmpIncidentalForListVO;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.tlemployee.service.ITlEmployeeService;
import com.hskn.hss.module.tlopetation.entity.TlOperation;
import com.hskn.hss.module.tlopetation.service.ITlOperationService;
import com.hskn.hss.module.tlworktype.entity.TlWorkType;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.module.worktype.service.IWorkTypeService;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.AttributeUtils;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.PageInfoConvent;
import com.hskn.hss.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-19
 */
@Service
public class TlEmpIncidentalServiceImpl extends ServiceImpl<TlEmpIncidentalMapper, TlEmpIncidental> implements ITlEmpIncidentalService {

    @Autowired
    TlEmpIncidentalMapper tlEmpIncidentalMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    SysDepartMapper sysDepartMapper;
    @Resource
    TlEmployeeMapper employeeMapper;
    @Resource
    ITlEmployeeService employeeService;
    @Resource
    ICostDictItemService costDictItemService;
    @Resource
    private SysDepartMapper departMapper;
    @Resource
    private ISysDepartService departService;
    @Resource
    private IWorkTypeService workTypeService;
    @Resource
    private ITlOperationService tlOperationService;
    @Resource
    private TlEmpIncidentalMapper empIncidentalMapper;

    @Override
    public int insert(InsertEmpIncidentalTO insertEmpIncidentalTO) throws HssException {
        String uid = LoginUtils.getUser().getUid();
        TlEmpIncidental tlEmpIncidental = JSONObject.parseObject(JSONObject.toJSONString(insertEmpIncidentalTO), TlEmpIncidental.class);
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();
        tlEmpIncidental.setCreateby(uid);
        tlEmpIncidental.setCreatetime(new Date());
        tlEmpIncidental.setDeptid(deptid);
        SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM");
        tlEmpIncidental.setMonth(dataFormat.format(tlEmpIncidental.getPaydate()));
        if (StringUtils.isNotEmpty(tlEmpIncidental.getEmpid())) {
            TlEmployee employee = employeeMapper.selectById(tlEmpIncidental.getEmpid());
            if (employee != null) {
                tlEmpIncidental.setWorkType(employee.getWorktype());
                tlEmpIncidental.setOperationId(employee.getPersontype());
                tlEmpIncidental.setEmpdeptid(employee.getDeptid());
            }
        }
        return tlEmpIncidentalMapper.insert(tlEmpIncidental);
    }

    @Override
    public int update(UpdateEmpIncidentalTO updateEmpIncidentalTO) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        TlEmpIncidental tlEmpIncidental = JSONObject.parseObject(JSONObject.toJSONString(updateEmpIncidentalTO), TlEmpIncidental.class);
        tlEmpIncidental.setUpdateby(uid);
        tlEmpIncidental.setUpdatetime(new Date());
        SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM");
        tlEmpIncidental.setMonth(dataFormat.format(tlEmpIncidental.getPaydate()));
        if (StringUtils.isNotEmpty(tlEmpIncidental.getEmpid())) {
            TlEmployee employee = employeeMapper.selectById(tlEmpIncidental.getEmpid());
            if (employee != null) {
                tlEmpIncidental.setWorkType(employee.getWorktype());
                tlEmpIncidental.setOperationId(employee.getPersontype());
                tlEmpIncidental.setEmpdeptid(employee.getDeptid());
            }
        }
        return tlEmpIncidentalMapper.updateById(tlEmpIncidental);
    }

    @Override
    public int deletebyid(ForIdsTO forIdsTO) throws HssException {
        return tlEmpIncidentalMapper.deleteBatchIds(forIdsTO.getIds());
    }

    @Override
    public TlEmpIncidental getDetail(EmpIncidentalForIdTO empIncidentalForIdTO) throws HssException {
        String id = empIncidentalForIdTO.getId();
        TlEmpIncidental tlEmpIncidental = tlEmpIncidentalMapper.selectById(id);
        SysDepart depart = sysDepartMapper.selectById(tlEmpIncidental.getEmpdeptid());
        TlEmployee employee = employeeMapper.selectById(tlEmpIncidental.getEmpid());
        if (employee != null) {
            tlEmpIncidental.setEmpName(employee.getName());
        }
        if (depart != null) {
            tlEmpIncidental.setEmpdeptName(depart.getDepartName());
        }
        return tlEmpIncidental;
    }

//    @Override
//    public List getSelectList(JSONObject params) {
//        Map<String , Object> map = new HashMap();
//        map.put("equipcode" , params.getString("equipcode"));
//        map.put("equiptypeid" , params.getString("equiptypeid"));
//        map.put("equipmodelid" , params.getString("equipmodelid"));
//        map.put("bindstatus" , params.getString("bindstatus"));
//
//        List resultList = tlEmpIncidentalMapper.getSelectList(map);
//        return resultList;
//    }


    @Override
    @DataScope(deptAlias = "empdeptid", userAlias = "createby")
    public TableDataInfo getList(EmpIncidentalListForPageTO empIncidentalListTO) throws HssException {
        Map<String, TlWorkType> workTypeMap = workTypeService.getWorkTypeMap(new QueryWrapper<>());
        Map<String, TlOperation> operationMap = tlOperationService.getTlOperationMap(new QueryWrapper<>());
        Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
        QueryWrapper<TlEmpIncidental> empSalaryQueryWrapper = new QueryWrapper<>();
        QueryWrapper<TlEmployee> employeeQueryWrapper = new QueryWrapper<>();
        Map<String, TlEmployee> employeeMap = null;
        if (StringUtils.isNotEmpty(empIncidentalListTO.getFullName()) || StringUtils.isNotEmpty(empIncidentalListTO.getJobNumber()) || StringUtils.isNotEmpty(empIncidentalListTO.getIdCardNo())) {
            employeeQueryWrapper.lambda().eq(TlEmployee::getName, empIncidentalListTO.getFullName());
            employeeQueryWrapper.lambda().eq(TlEmployee::getIdcardnum, empIncidentalListTO.getIdCardNo());
            employeeQueryWrapper.lambda().eq(TlEmployee::getEmplnum, empIncidentalListTO.getJobNumber());
            employeeMap = employeeService.getEmpMap(employeeQueryWrapper);
        }
        if (null != employeeMap) {
            empSalaryQueryWrapper.lambda().eq(TlEmpIncidental::getEmpid, employeeMap.keySet());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTO.getStartdate()) && StringUtils.isNotEmpty(empIncidentalListTO.getEnddate())) {
            empSalaryQueryWrapper.lambda().between(TlEmpIncidental::getPaydate, AttributeUtils.timeCompletion(empIncidentalListTO.getStartdate(), 's')
                    , AttributeUtils.timeCompletion(empIncidentalListTO.getEnddate(), 'e'));
        }
        if (StringUtils.isNotEmpty(empIncidentalListTO.getCostType())) {
            empSalaryQueryWrapper.lambda().eq(TlEmpIncidental::getCosttype, empIncidentalListTO.getCostType());
        }
        if (empIncidentalListTO.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(empIncidentalListTO.getParams().get("dataScope").toString())) {
            empSalaryQueryWrapper.lambda().apply(empIncidentalListTO.getParams().get("dataScope").toString());
        }
        empSalaryQueryWrapper.lambda().orderByDesc(TlEmpIncidental::getCreatetime);
        List<TlEmpIncidental> empSalaryList = tlEmpIncidentalMapper.selectList(empSalaryQueryWrapper);
        employeeMap = employeeService.getEmpMap(new QueryWrapper<>());
        Map<String, CostDictItem> costDictItemMap = costDictItemService.getCostDictItemMap(new QueryWrapper<>());
        for (TlEmpIncidental tlEmpSalary : empSalaryList) {
            if (employeeMap.containsKey(tlEmpSalary.getEmpid())) {
                tlEmpSalary.setEmpName(employeeMap.get(tlEmpSalary.getEmpid()).getName());
                tlEmpSalary.setIdcardnum(employeeMap.get(tlEmpSalary.getEmpid()).getIdcardnum());
                tlEmpSalary.setEmplnum(employeeMap.get(tlEmpSalary.getEmpid()).getEmplnum());
            }
            if (workTypeMap.containsKey(tlEmpSalary.getWorkType())) {
                tlEmpSalary.setWorkTypeName(workTypeMap.get(tlEmpSalary.getWorkType()).getWorktype());
            }
            if (operationMap.containsKey(tlEmpSalary.getOperationId())) {
                tlEmpSalary.setOperationName(operationMap.get(tlEmpSalary.getOperationId()).getOperationtype());
            }
            if (departMap.containsKey(tlEmpSalary.getEmpdeptid())) {
                tlEmpSalary.setEmpdeptName(departMap.get(tlEmpSalary.getEmpdeptid()).getDepartName());
            }
            if (costDictItemMap.containsKey(tlEmpSalary.getCosttype())) {
                tlEmpSalary.setCosttypeName(costDictItemMap.get(tlEmpSalary.getCosttype()).getCostname());
            }
        }
        List<EmpIncidentalForListVO> empIncidentalForListVOList = JSONObject.parseArray(JSONObject.toJSONString(empSalaryList)
                , EmpIncidentalForListVO.class);
        PageInfoConvent<EmpIncidentalForListVO> empSalaryPageInfoConvent = new PageInfoConvent<EmpIncidentalForListVO>(empIncidentalListTO.getPage(), empIncidentalListTO.getSize(), empIncidentalForListVOList);
        TableDataInfo tableDataInfo = new TableDataInfo(empSalaryPageInfoConvent.getList(), empIncidentalForListVOList.size());
        return tableDataInfo;
    }

    @Override
    public void excelReader(List<TlEmpIncidental> empIncidentalList) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        List<SysDepart> departList = departMapper.selectList(new QueryWrapper<>());
        List<TlEmployee> employeeList = employeeMapper.selectList(new QueryWrapper<>());
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<SysDepart> departNameNotNull = depart -> StringUtils.isNotEmpty(depart.getDepartName());
            departList = departList.stream().filter(departNameNotNull).collect(Collectors.toList());
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getDepartName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, TlEmployee> employeeMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<TlEmployee> nameNotNull = employee -> StringUtils.isNotEmpty(employee.getName());
            employeeList = employeeList.stream().filter(nameNotNull).collect(Collectors.toList());
            employeeMap = GroupingByUtils.getGroupingForMapEntity(employeeList, TlEmployee::getName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        int num = 1;
        String str = "";
        for (TlEmpIncidental empIncidental : empIncidentalList) {
            empIncidental.setCreatetime(new Date());
            empIncidental.setCreateby(uid);
            if (StringUtils.isNotEmpty(empIncidental.getEmpdeptName())) {
                if (departMap.containsKey(empIncidental.getEmpdeptName())) {
                    empIncidental.setEmpdeptid(departMap.get(empIncidental.getEmpdeptName()).getId());
                    empIncidental.setDeptid(departMap.get(empIncidental.getEmpdeptName()).getId());
                } else {
                    str += "第" + num + "条的“‘所属机构’:‘" + empIncidental.getEmpdeptName() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“所属机构”不能为空;##";
            }
            if (StringUtils.isNotEmpty(empIncidental.getEmpName())) {
                if (employeeMap.containsKey(empIncidental.getEmpName())) {
                    empIncidental.setEmpid(employeeMap.get(empIncidental.getEmpName()).getId());
                } else {
                    str += "第" + num + "条的“‘姓名’:‘" + empIncidental.getEmpdeptName() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“姓名”不能为空;##";
            }
            if (Objects.isNull(empIncidental.getPaydate())) {
                str += "第" + num + "条的“缴费时间”格式不正确;##";
            }
            num++;
        }
        if (StringUtils.isNotEmpty(str)) {
            throw new ExcelReaderDataException("您导入的数据:##" + str);
        }
    }

    @Override
    @DataScope(deptAlias = "empdeptid", userAlias = "createby")
    public List<TlEmpIncidental> getTlEmpIncidental(EmpIncidentalListTO empIncidentalListTo, SimpleDateFormat format) throws ParseException {
        List<TlEmployee> employeeList = null;
        QueryWrapper<TlEmployee> employeeQueryWrapper = new QueryWrapper<>();
        QueryWrapper<TlEmpIncidental> empIncidentalQueryWrapper = new QueryWrapper<>();
        if (empIncidentalListTo.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(empIncidentalListTo.getParams().get("dataScope").toString())) {
            empIncidentalQueryWrapper.lambda().apply(empIncidentalListTo.getParams().get("dataScope").toString());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTo.getFullName())) {
            employeeQueryWrapper.lambda().eq(TlEmployee::getName, empIncidentalListTo.getFullName());
            employeeList = employeeMapper.selectList(employeeQueryWrapper);
            Map<String, TlEmployee> employeeMap = GroupingByUtils.getGroupingForMapEntity(employeeList, TlEmployee::getName,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
            empIncidentalQueryWrapper.lambda().in(TlEmpIncidental::getEmpid, employeeMap.keySet());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTo.getIdCardNo())) {
            employeeQueryWrapper.lambda().eq(TlEmployee::getIdcardnum, empIncidentalListTo.getIdCardNo());
            employeeList = employeeMapper.selectList(employeeQueryWrapper);
            Map<String, TlEmployee> employeeMap = GroupingByUtils.getGroupingForMapEntity(employeeList, TlEmployee::getIdcardnum,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
            empIncidentalQueryWrapper.lambda().in(TlEmpIncidental::getEmpid, employeeMap.keySet());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTo.getJobNumber())) {
            employeeQueryWrapper.lambda().eq(TlEmployee::getEmplnum, empIncidentalListTo.getJobNumber());
            employeeList = employeeMapper.selectList(employeeQueryWrapper);
            Map<String, TlEmployee> employeeMap = GroupingByUtils.getGroupingForMapEntity(employeeList, TlEmployee::getEmplnum,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
            empIncidentalQueryWrapper.lambda().in(TlEmpIncidental::getEmpid, employeeMap.keySet());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTo.getCostType())) {
            empIncidentalQueryWrapper.lambda().eq(TlEmpIncidental::getCosttype, empIncidentalListTo.getCostType());
        }
        if (empIncidentalListTo.getIds() != null && !empIncidentalListTo.getIds().isEmpty()) {
            empIncidentalQueryWrapper.lambda().in(TlEmpIncidental::getId, empIncidentalListTo.getIds());
        }
        if (StringUtils.isNotEmpty(empIncidentalListTo.getStartTime()) && StringUtils.isNotEmpty(empIncidentalListTo.getEndTime())) {
            empIncidentalQueryWrapper.lambda().ge(TlEmpIncidental::getCreatetime, format.parse(empIncidentalListTo.getStartTime()));
            empIncidentalQueryWrapper.lambda().le(TlEmpIncidental::getCreatetime, format.parse(empIncidentalListTo.getEndTime()));
        }
        List<TlEmpIncidental> empIncidentalList = empIncidentalMapper.selectList(empIncidentalQueryWrapper);
        return empIncidentalList;
    }
}
